#include "aduc812.h"
#include "max.h"
#include "led.h"
#include "keyboard.h"
#include "rs232.h"
#include "repl.h"

unsigned long time = 0;

unsigned char sound_flag = 0;
unsigned char led_flag = 0;
unsigned char keyboard_flag = 0;
unsigned long sound_time = 0;
unsigned long led_time = 0;
unsigned long keyboard_time = 0;

char old_key = -1;

void int_vector(unsigned char __xdata * address, void * vector) {
	unsigned char __xdata * tmp;
	* address = 0x02;
	tmp = (unsigned char __xdata *) (address + 1);
	* tmp = (unsigned char) ((unsigned short) vector >> 8);
	* ++tmp = (unsigned char) vector;
}

void init_timer0_16(char TH, char TL, char priority, void * vector) {
	int_vector(0x200B, vector);
	TMOD = (TMOD & 0xF0) | 0x01;
	TH0 = TH;
	TL0 = TL;
	PCON &= 0x7F;
	ET0 = 1;
	PT0 = priority ? 1 : 0;
	TR0 = 1;
	EA = 1;
}

void init_timer0(char delay, char priority, void * vector) {
	int_vector(0x200B, vector);
	TMOD = (TMOD & 0xF0) | 0x02;
	TH0 = TL0 = 0xFF - delay;
	PCON &= 0x7F;							// double baud rate control = 0
	ET0 = 1;									// enable timer 0 interrupt
	PT0 = priority ? 1 : 0;		// set priority
	TR0 = 1;									// start timer 0
	EA = 1;										// enable interrupt
}

void init_timer1(char delay, char priority, void * vector) {
	int_vector(0x2023, vector);
	TMOD = (TMOD & 0x0F) | 0x20;
	TH1 = TL1 = 0xFF - delay;
	PCON &= 0x7F;
	ET1 = 1;
	PT1 = priority ? 1 : 0;
	TR1 = 1;
	EA = 1;
}

void beep_sound() {
	sound_flag = 1;
	sound_time = time;
}

void beep_led() {
	led_flag = 1;
	led_time = time;
}

void main_int() __interrupt(0) {
	char tmp;
	/* sound */
	if (sound_flag) {
		if (time > sound_time + 10) sound_flag = 0;
		if (time % 2 == 0) write_max(ENA, read_max(ENA) | 0x18);
		else write_max(ENA, read_max(ENA) & 0xE3);
	}
	/* leds */
	if (led_flag) {
		if (time > led_time + 10) { led_flag = 0; leds(0x00); }
		else leds(0xFF);
	}
	/* scan keyboard */
	tmp = keyboard_scan();
	if (tmp >= 0 && !keyboard_flag) {
					old_key = tmp;
					beep_led(); beep_sound();
					write_rs232(map(tmp));
					keyboard_flag = 1;
					keyboard_time = time;
	}
	if (tmp != old_key || (keyboard_flag && time > keyboard_time + 500)) keyboard_flag = 0;
	TH0 = 0xFC;
	TL0 = 0x65;
	time++;
}

void init_main_int() {
	init_timer0_16(0xFC, 0x65, 0, (void *) main_int);
}
